home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_500 / wiconify / wiconify-source.lzh / Source / wIconify.c < prev    next >
C/C++ Source or Header  |  1991-04-19  |  22KB  |  660 lines

  1. /*
  2.  *  WICONIFY    A utility that allows you to iconify any Intuition window
  3.  *              on any screen, and to open WB windows on any screen.
  4.  *
  5.  *  wIconify.c  Main loader code.
  6.  *
  7.  *  Copyright 1990 by Davide P. Cervone, all rights reserved.
  8.  *  You may use this code, provided this copyright notice is kept intact.
  9.  */
  10.  
  11. #include <intuition/intuitionbase.h>
  12. #include <devices/input.h>
  13. #include "wIconify.h"
  14. #include "wSetup.h"
  15. #include "wMenu.h"
  16. #include <libraries/dosextens.h>
  17.  
  18. extern struct IntuitionBase *IntuitionBase;
  19. extern struct GfxBase *GfxBase;
  20. struct LayersBase *LayersBase;
  21. extern struct SysBase *SysBase;
  22. extern struct DOSBase *DOSBase;
  23.  
  24. static char *program   = PROGRAM;
  25. static char *copyright = COPYRIGHT;
  26.  
  27. static char *handler   = HANDLERCODE2;      /* The name of the handler file */
  28. static char *HANDLER   = HANDLERCODE1;
  29.  
  30. static char *InitFile = INITFILENAME2;      /* the Init file */
  31. static char *INITFILE = INITFILENAME1;
  32.  
  33. #define DEFAULTCOMMAND      "NEWSHELL"      /* the default CLI command */
  34. #define K                   *1024           /* for things like 2K */
  35.  
  36. static struct HandlerData *HandlerData;     /* data shared with handler */
  37. static long Segment;                        /* The loaded handler segment */
  38. static APTR HandlerTask;                    /* The process created */
  39.  
  40. static struct MsgPort *InputPort;           /* To talk to Input.Device */
  41. static struct IOStdReq *InputBlock;         /* IO block for Input.Device */
  42. static int    InputDevice;                  /* Is Input.Device open? */
  43. static int    VectorsSet;                   /* TRUE after SetFunction */
  44. static int    HandlerAdded;                 /* TRUE after TellInputDevice */
  45. static int    AllOK;                        /* TRUE after ActivateIconify */
  46.  
  47.  
  48. #define vSETFUNC(lvo,func)  SetFunction(IntuitionBase,&lvo,var(func))
  49. #define VSETFUNC(lvo,func)  SetFunction(IntuitionBase,&lvo,VAR(func))
  50.  
  51. #define HANDLERPROC     ((struct Process *)HandlerTask)
  52.  
  53.  
  54. struct Menu *wMenuBar;              /* The wIconify window's menu bar */
  55. struct wMenuItem *OpenWindowMenu;   /* the OpenOn sub-menu */
  56. char *HiResCLICommand;              /* The HIRES NewCLI command string */
  57. char *LoResCLICommand;              /* The LOWRES NewCLI command string */
  58. long StackSize;                     /* The CLI command stack size */
  59. struct Image *DefaultImage;         /* Image for icons that don't give one */
  60. struct Image *DefaultSelect;        /* Select image for icons without one */
  61. struct Image *DefaultMask;          /* Default mask for Image or Select */
  62. struct Image *DefaultScreenImage;   /* Image for screens that don't give one */
  63. struct Image *DefaultScreenSelect;  /* Select image for screenss without one */
  64. struct Image *DefaultScreenMask;    /* Default mask for screen icons */
  65. ULONG DefaultFlags;                 /* Icon flags default icons */
  66. ULONG DefaultScreenFlags;           /* Icon flags default screen icons */
  67. struct Ignore *IgnoreScreen;        /* List of screen titles to ignore */
  68. UBYTE IconifyKey = WICONIFYKEY;     /* Key for iconifying active window */
  69. UBYTE ActivateKey = WACTIVEKEY;     /* Key for activating wIconify window */
  70. UWORD IconifyQuals = WQUALIFIERS;   /* Qualifiers for iconifying a window */
  71. UWORD IconifyDisquals;              /* Qualifiers that prevent iconifying */
  72. UWORD IconifyChange = WCHANGEQUALS; /* Qualifiers for changing refresh type */
  73. UWORD ActivateQuals = WACTIVEQUAL;  /* Qualifiers for activating wIconify */
  74. int IconifyPriority;                /* Priority of handler as a process */
  75. int HandlerPriority = 51;           /* Priority of Input Handler in chain */
  76. UWORD *ScreenColors;                /* Default New Screen color map */
  77. int AutoResize = TRUE;              /* Size windows to fit screen? */
  78. int ScreenType = OW_ACTIVESCRN;     /* Where to open WB windows */
  79.  
  80.  
  81. /*
  82.  *  SetWindowMenu()
  83.  *
  84.  *  Set the menu flags for the OpenOn submenu so that the proper ones
  85.  *  are checked.
  86.  */
  87.  
  88. static void SetWindowMenu(ScreenType,SizeToFit)
  89. int ScreenType,SizeToFit;
  90. {
  91.    short i;
  92.  
  93.    if (ScreenType != NOCHANGE)
  94.    {
  95.       for (i=OW_ACTIVESCRN; i<=OW_REALWB; i++)
  96.       {
  97.          if (i == ScreenType)
  98.            OpenWindowMenu[i].Item.Flags |=  CHECKED;
  99.           else
  100.            OpenWindowMenu[i].Item.Flags &= ~CHECKED;
  101.       }
  102.    }
  103.    if (SizeToFit != NOCHANGE)
  104.    {
  105.       if (SizeToFit)
  106.          OpenWindowMenu[OW_AUTORESIZE].Item.Flags |=  CHECKED;
  107.         else
  108.          OpenWindowMenu[OW_AUTORESIZE].Item.Flags &= ~CHECKED;
  109.    }
  110. }
  111.  
  112.  
  113. /*
  114.  *  FreeImage()
  115.  *
  116.  *  If the image is not the defualt image (which was not allocated dynamically),
  117.  *  then free any image data bitplanes, and free the image structure itself.
  118.  */
  119.  
  120. static void FreeImage(theImage)
  121. struct Image *theImage;
  122. {
  123.    if (theImage != var(DefaultIcon) && theImage != var(DefaultScreenIcon))
  124.    {
  125.       if (theImage->ImageData) FreeRaster(theImage->ImageData,
  126.          theImage->Width,theImage->Height*theImage->Depth);
  127.       FREESTRUCT(Image,theImage);
  128.    }
  129. }
  130.  
  131.  
  132. /*
  133.  *  CleanUpDefaults()
  134.  *
  135.  *  Free any allocated memory, specifically, the NewCLI strings, the
  136.  *  default images, and the ignored-screen title list.
  137.  */
  138.  
  139. static void CleanUpDefaults()
  140. {
  141.    struct Ignore *nextIgnore;
  142.  
  143.    if (HiResCLICommand)     FREECHAR(HiResCLICommand);
  144.    if (LoResCLICommand)     FREECHAR(LoResCLICommand);
  145.    if (DefaultImage)        FreeImage(DefaultImage);
  146.    if (DefaultSelect)       FreeImage(DefaultSelect);
  147.    if (DefaultMask)         FreeImage(DefaultMask);
  148.    if (DefaultScreenImage)  FreeImage(DefaultScreenImage);
  149.    if (DefaultScreenSelect) FreeImage(DefaultScreenSelect);
  150.    if (DefaultScreenMask)   FreeImage(DefaultScreenMask);
  151.    while (IgnoreScreen)
  152.    {
  153.       nextIgnore = IgnoreScreen->Next;
  154.       if (IgnoreScreen->Title) FREECHAR(IgnoreScreen->Title);
  155.       FREESTRUCT(Ignore,IgnoreScreen);
  156.       IgnoreScreen = nextIgnore;
  157.    }
  158. }
  159.  
  160.  
  161. /*
  162.  *  DoExit()
  163.  *
  164.  *  General purpose error-exit routine.  Print an error message if one was
  165.  *  supplied (it can have up to three parameters), and then clean up any
  166.  *  memory, libraries, etc. that need to be handled before exiting.
  167.  */
  168.  
  169. void DoExit(s,x1,x2,x3)
  170. char *s, *x1, *x2, *x3;
  171. {
  172.    long status = EXIT_OK;
  173.    extern int UnSetVectors();
  174.    extern int TellInputDevice();
  175.    
  176.    if (s != NULL)
  177.    {
  178.       printf(s,x1,x2,x3);
  179.       printf("\n");
  180.       status = EXIT_ERROR;
  181.    }
  182.  
  183.    if (VectorsSet) if (!UnSetVectors())
  184.       printf("Fatal Error:  Can't remove SetFunction Vectors!"),
  185.       Segment = NULL;
  186.    if (HandlerAdded)
  187.    {
  188.       HandlerAdded = FALSE;
  189.       if (!TellInputDevice(IND_REMHANDLER))
  190.          printf("Fatal Error:  Can't remove Input Handler!"),
  191.          Segment = NULL;
  192.    }
  193.  
  194.    if (HandlerTask)
  195.    {
  196.       Signal(HandlerTask,CANCELSIGNAL);
  197.       Wait(OKSIGNAL| CANCELSIGNAL);
  198.    }
  199.    if (!AllOK)        CleanUpDefaults();
  200.    if (Segment)       UnLoadSeg(Segment), printf("wIconify Removed\n");
  201.    if (InputDevice)   CloseDevice(InputBlock);
  202.    if (InputBlock)    DeleteStdIO(InputBlock);
  203.    if (InputPort)     DeletePort(InputPort);
  204.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  205.    if (GfxBase)       CloseLibrary(GfxBase);
  206.    if (LayersBase)    CloseLibrary(LayersBase);
  207.    exit(status);
  208. }
  209.  
  210.  
  211. /*
  212.  *  CheckLibOpen()
  213.  *
  214.  *  Call OpenLibrary() for the specified library, and check that the 
  215.  *  open succeeded.
  216.  */
  217.  
  218. static void CheckLibOpen(lib,name,rev)
  219. APTR *lib;
  220. char *name;
  221. int rev;
  222. {
  223.    extern APTR OpenLibrary();
  224.  
  225.    if ((*lib = OpenLibrary(name,(LONG)rev)) == NULL)
  226.       DoExit("Can't open %s",name);
  227. }
  228.  
  229.  
  230. /*
  231.  *  TellInputDevice()
  232.  *
  233.  *  Create a port and I/O block, then open the input device.  Set up the
  234.  *  I/O block to add or remove the input handler, and send the request
  235.  *  to the input device.  Finally, close the device and delete the
  236.  *  I/O block and port.
  237.  */
  238.  
  239. static int TellInputDevice(function)
  240. int function;
  241. {
  242.    long status;
  243.    extern struct MsgPort *CreatePort();
  244.    extern struct IOStdReq *CreateStdIO();
  245.  
  246.    if ((InputPort = CreatePort(NULL,0)) == NULL) return(FALSE);
  247.    if ((InputBlock = CreateStdIO(InputPort)) == NULL) return(FALSE);
  248.    InputDevice = (OpenDevice("input.device",0,InputBlock,0) == 0);
  249.    if (InputDevice == FALSE) return(FALSE);
  250.    
  251.    InputBlock->io_Command = (long) function;
  252.    InputBlock->io_Data    = (APTR) var(Handler_Interrupt);
  253.    if (status = DoIO(InputBlock)) return(FALSE);
  254.  
  255.    CloseDevice(InputBlock); InputDevice = FALSE;
  256.    DeleteStdIO(InputBlock); InputBlock = NULL;
  257.    DeletePort(InputPort);   InputPort = NULL;
  258.    return(TRUE);
  259. }
  260.  
  261.  
  262. /*
  263.  *  SetDefaults()
  264.  *
  265.  *  If the initialization file did not specify an iconify key or an
  266.  *  activation key, set them to the defaults.  Set the default image
  267.  *  If none was given.  Set the default HIRES command if none was
  268.  *  provided.  Check the Image and Select image sizes to see that they
  269.  *  match, and give a warning of not.
  270.  */
  271.  
  272. static void SetDefaults()
  273. {
  274.    if (IconifyKey == 0)
  275.    {
  276.       IconifyKey = WICONIFYKEY;
  277.       IconifyQuals = WQUALIFIERS;
  278.       IconifyDisquals = 0;
  279.    }
  280.    if (ActivateKey == 0)
  281.    {
  282.       ActivateKey = WACTIVEKEY;
  283.       ActivateQuals = WACTIVEQUAL;
  284.    }
  285.    if (DefaultImage == NULL)       DefaultImage = var(DefaultIcon);
  286.    if (DefaultScreenImage == NULL) DefaultScreenImage = var(DefaultScreenIcon);
  287.    if (HiResCLICommand == NULL)
  288.    {
  289.       if (NEWCHAR(HiResCLICommand,strlen(DEFAULTCOMMAND)))
  290.          strcpy(HiResCLICommand,DEFAULTCOMMAND);
  291.    }
  292.    if (DefaultSelect)
  293.    {
  294.       if (DefaultImage->Width  != DefaultSelect->Width ||
  295.           DefaultImage->Height != DefaultSelect->Height)
  296.         printf("Warning: DEFAULT_IMAGE and DEFAULT_SELECT sizes don't match\n");
  297.    }
  298.    if (DefaultScreenSelect)
  299.    {
  300.       if (DefaultScreenImage->Width  != DefaultScreenSelect->Width ||
  301.           DefaultScreenImage->Height != DefaultScreenSelect->Height)
  302.         printf("Warning:  SCREEN_IMAGE and SCREEN_SELECT sizes don't match\n");
  303.    }
  304.    if (DefaultMask)
  305.    {
  306.       if (DefaultImage->Width  != DefaultMask->Width ||
  307.           DefaultImage->Height != DefaultMask->Height)
  308.       {
  309.          printf("Error:  DEFAULT_IMAGE and DEFAULT_MASK sizes don't match\n");
  310.          FreeImage(DefaultMask); DefaultMask = NULL;
  311.       }
  312.    }
  313.    if (DefaultScreenMask)
  314.    {
  315.       if (DefaultScreenImage->Width  != DefaultScreenMask->Width ||
  316.           DefaultScreenImage->Height != DefaultScreenMask->Height)
  317.       {
  318.          printf("Error:  SCREEN_IMAGE and SCREEN_MASK sizes don't match\n");
  319.          FreeImage(DefaultScreenMask); DefaultScreenMask = NULL;
  320.       }
  321.    }
  322.    if (StackSize == 0) StackSize = 8K; else
  323.    if (StackSize < 2K) StackSize = 2K;
  324.    var(Handler_Interrupt)->is_Node.ln_Pri = HandlerPriority;
  325. }
  326.  
  327.  
  328.  
  329. /*
  330.  *  SetVectors()
  331.  *
  332.  *  Set the Intuition library vectors for the Intuition functions
  333.  *  to the routines specified by the handler.  Save the old routine
  334.  *  pointers for later replacement.
  335.  */
  336.  
  337. static void SetVectors()
  338. {
  339.    VAR(OldOpenWindow)      = vSETFUNC(LVOOpenWindow,aOpenWindow);
  340.    VAR(OldCloseWindow)     = vSETFUNC(LVOCloseWindow,aCloseWindow);
  341.    VAR(OldOpenScreen)      = vSETFUNC(LVOOpenScreen,aOpenScreen);
  342.    VAR(OldCloseScreen)     = vSETFUNC(LVOCloseScreen,aCloseScreen);
  343.    VAR(OldSetWindowTitles) = vSETFUNC(LVOSetWindowTitles,aSetWindowTitles);
  344.    VAR(OldWindowToFront)   = vSETFUNC(LVOWindowToFront,aWindowToFront);
  345.    VAR(OldWindowToBack)    = vSETFUNC(LVOWindowToBack,aWindowToBack);
  346.    VAR(OldActivateWindow)  = vSETFUNC(LVOActivateWindow,aActivateWindow);
  347.    VAR(OldBuildSysRequest) = vSETFUNC(LVOBuildSysRequest,aBuildSysRequest);
  348.    VAR(OldFreeSysRequest)  = vSETFUNC(LVOFreeSysRequest,aFreeSysRequest);
  349.    VAR(OldAutoRequest)     = vSETFUNC(LVOAutoRequest,aAutoRequest);
  350.    VectorsSet = TRUE;
  351. }
  352.  
  353.  
  354. /*
  355.  *  UnSetVectors()
  356.  *
  357.  *  Replace the old Intuition library vectors, but make sure that no one
  358.  *  else has changed them behind our back.  If they are not the same as
  359.  *  what we set them to originally, then put back the ones that we found,
  360.  *  and return an error status.
  361.  */
  362.  
  363. static int UnSetVectors()
  364. {
  365.    long NewOpenWindow,NewCloseWindow;
  366.    long NewOpenScreen,NewCloseScreen;
  367.    long NewSetWindowTitles;
  368.    long NewWindowToFront,NewWindowToBack,NewActivateWindow;
  369.    long NewBuildSysRequest,NewFreeSysRequest,NewAutoRequest;
  370.    int status = TRUE;
  371.  
  372.    NewOpenWindow      = VSETFUNC(LVOOpenWindow,OldOpenWindow);
  373.    NewCloseWindow     = VSETFUNC(LVOCloseWindow,OldCloseWindow);
  374.    NewOpenScreen      = VSETFUNC(LVOOpenScreen,OldOpenScreen);
  375.    NewCloseScreen     = VSETFUNC(LVOCloseScreen,OldCloseScreen);
  376.    NewSetWindowTitles = VSETFUNC(LVOSetWindowTitles,OldSetWindowTitles);
  377.    NewWindowToFront   = VSETFUNC(LVOWindowToFront,OldWindowToFront);
  378.    NewWindowToBack    = VSETFUNC(LVOWindowToBack,OldWindowToBack);
  379.    NewActivateWindow  = VSETFUNC(LVOActivateWindow,OldActivateWindow);
  380.    NewBuildSysRequest = VSETFUNC(LVOBuildSysRequest,OldBuildSysRequest);
  381.    NewFreeSysRequest  = VSETFUNC(LVOFreeSysRequest,OldFreeSysRequest);
  382.    NewAutoRequest     = VSETFUNC(LVOAutoRequest,OldAutoRequest);
  383.  
  384.    if (NewOpenWindow      != (long) var(aOpenWindow)      ||
  385.        NewCloseWindow     != (long) var(aCloseWindow)     ||
  386.        NewOpenScreen      != (long) var(aOpenScreen)      ||
  387.        NewCloseScreen     != (long) var(aCloseScreen)     ||
  388.        NewSetWindowTitles != (long) var(aSetWindowTitles) ||
  389.        NewWindowToFront   != (long) var(aWindowToFront)   ||
  390.        NewWindowToBack    != (long) var(aWindowToBack)    ||
  391.        NewActivateWindow  != (long) var(aActivateWindow)  ||
  392.        NewBuildSysRequest != (long) var(aBuildSysRequest) ||
  393.        NewFreeSysRequest  != (long) var(aFreeSysRequest)  ||
  394.        NewAutoRequest     != (long) var(aAutoRequest))
  395.    {
  396.       SetFunction(IntuitionBase,&LVOOpenWindow,NewOpenWindow);
  397.       SetFunction(IntuitionBase,&LVOCloseWindow,NewCloseWindow);
  398.       SetFunction(IntuitionBase,&LVOOpenScreen,NewOpenScreen);
  399.       SetFunction(IntuitionBase,&LVOCloseScreen,NewCloseScreen);
  400.       SetFunction(IntuitionBase,&LVOSetWindowTitles,NewSetWindowTitles);
  401.       SetFunction(IntuitionBase,&LVOWindowToFront,NewWindowToFront);
  402.       SetFunction(IntuitionBase,&LVOWindowToBack,NewWindowToBack);
  403.       SetFunction(IntuitionBase,&LVOActivateWindow,NewActivateWindow);
  404.       SetFunction(IntuitionBase,&LVOBuildSysRequest,NewBuildSysRequest);
  405.       SetFunction(IntuitionBase,&LVOFreeSysRequest,NewFreeSysRequest);
  406.       SetFunction(IntuitionBase,&LVOAutoRequest,NewAutoRequest);
  407.       VectorsSet = status = FALSE;
  408.    }
  409.    return(status);
  410. }
  411.  
  412.  
  413. /*
  414.  *  GetVariables()
  415.  *
  416.  *  Get copies of the Handler variables that the loader will need during
  417.  *  the setup process.
  418.  */
  419.  
  420. static void GetVariables()
  421. {
  422.    wMenuBar = var(wMenu);
  423.    OpenWindowMenu = var(OpenWindowMenu);
  424.    ScreenColors = var(Colors);
  425. }
  426.  
  427.  
  428. /*
  429.  *  SetVariables()
  430.  *
  431.  *  Once the loader has does its initialization, set the variables
  432.  *  required by the handler.
  433.  */
  434.  
  435. static void SetVariables()
  436. {
  437.    VAR(IntuitionBase)       = IntuitionBase;
  438.    VAR(GfxBase)             = GfxBase;
  439.    VAR(LayersBase)          = LayersBase;
  440.    VAR(SysBase)             = SysBase;
  441.    VAR(DOSBase)             = DOSBase;
  442.    VAR(HiResCLICommand)     = HiResCLICommand;
  443.    VAR(LoResCLICommand)     = LoResCLICommand;
  444.    VAR(StackSize)           = StackSize;
  445.    VAR(DefaultImage)        = DefaultImage;
  446.    VAR(DefaultSelect)       = DefaultSelect;
  447.    VAR(DefaultMask)         = DefaultMask;
  448.    VAR(DefaultScreenImage)  = DefaultScreenImage;
  449.    VAR(DefaultScreenSelect) = DefaultScreenSelect;
  450.    VAR(DefaultScreenMask)   = DefaultScreenMask;
  451.    VAR(DefaultFlags)        = DefaultFlags;
  452.    VAR(DefaultScreenFlags)  = DefaultScreenFlags;
  453.    VAR(IgnoreScreen)        = IgnoreScreen;
  454.    VAR(IconifyKey)          = IconifyKey;
  455.    VAR(ActivateKey)         = ActivateKey;
  456.    VAR(IconifyQuals)        = IconifyQuals;
  457.    VAR(IconifyDisquals)     = IconifyDisquals;
  458.    VAR(IconifyChange)       = IconifyChange;
  459.    VAR(ActivateQuals)       = ActivateQuals;
  460.    SetWindowMenu(ScreenType,AutoResize);
  461. }
  462.  
  463.  
  464. /*
  465.  *  GetIconifyVars()
  466.  *
  467.  *  When it comes time to remove the handler, recover the initialized
  468.  *  data from the HandlerData structure, and set the flags so that cleanup
  469.  *  will proceed properly.
  470.  */
  471.  
  472. static void GetIconifyVars()
  473. {
  474.    IntuitionBase       = VAR(IntuitionBase);
  475.    GfxBase             = VAR(GfxBase);
  476.    LayersBase          = VAR(LayersBase);
  477.    HiResCLICommand     = VAR(HiResCLICommand);
  478.    LoResCLICommand     = VAR(LoResCLICommand);
  479.    DefaultImage        = VAR(DefaultImage);
  480.    DefaultSelect       = VAR(DefaultSelect);
  481.    DefaultMask         = VAR(DefaultMask);
  482.    DefaultScreenImage  = VAR(DefaultScreenImage);
  483.    DefaultScreenSelect = VAR(DefaultScreenSelect);
  484.    DefaultScreenMask   = VAR(DefaultScreenMask);
  485.    IgnoreScreen        = VAR(IgnoreScreen);
  486.    Segment             = var(Segment);
  487.    VectorsSet          = TRUE;
  488.    HandlerAdded        = TRUE;
  489.    AllOK               = FALSE;
  490.    HandlerTask         = NULL;
  491. }
  492.  
  493.  
  494. /*
  495.  *  LoadIconify()
  496.  *
  497.  *  Attempt to load the handler code (try different directories if not found).
  498.  *  Call the handler's setup routine and get the HandlerData pointer.
  499.  *  Check the version of the handler to be sure it's OK to use with this 
  500.  *  loader.  Set the Segment and ParentTask pointer of the HandlerData.
  501.  */
  502.  
  503. static void LoadIconify()
  504. {
  505.    struct HandlerData *(*Setup)();
  506.  
  507.    if ((Segment = LoadSeg(HANDLER)) == NULL)
  508.       if ((Segment = LoadSeg(handler)) == NULL)
  509.          DoExit("Can't load %s",handler);
  510.    Setup = (struct HandlerData *(*)()) ((Segment << 2) + 4);
  511.    HandlerData = (*Setup)(MAJLOADVERS,MINLOADVERS);
  512.    if (HandlerData)
  513.    {
  514.       if (var(MajVers) < MAJICONVERS ||
  515.          (var(MajVers) == MAJICONVERS && var(MinVers) < MINICONVERS))
  516.              DoExit("Version mismatch with %s",HANDLER);
  517.    } else {
  518.       DoExit("%s reports a version mismatch",HANDLER);
  519.    }
  520.    var(Segment)    = Segment;
  521.    var(ParentTask) = FindTask(NULL);
  522. }
  523.  
  524.  
  525. /*
  526.  *  CreateIconify()
  527.  *
  528.  *  Once the handler is loader, attempt to create a process from it.
  529.  *  Get a pointer to the handler process, and clear its console task
  530.  *    since inheriting this pointer can cause errors in the NewCLI command.
  531.  *    (this is a kludge, and should really be done by CreateProc()).
  532.  *  Wait for the handler to signal that it is ready to go, or for a user
  533.  *    initiated cancel.
  534.  */
  535.  
  536. static void CreateIconify()
  537. {
  538.    ULONG Signal;
  539.    int Pri = IconifyPriority;
  540.    static char *HandlerName = " wIconify-Handler ";
  541.  
  542.    if (CreateProc(HandlerName,Pri,Segment,STACKSIZE) == NULL)
  543.       DoExit("Can't create wIconify-Handler process");
  544.    HandlerTask = FindTask(HandlerName);
  545.    if (HandlerTask == NULL) DoExit("Can't Find Handler Task");
  546.    HANDLERPROC->pr_ConsoleTask = NULL;
  547.    Signal = Wait(OKSIGNAL| CANCELSIGNAL);
  548.    if (Signal & CANCELSIGNAL)
  549.       DoExit("wIconify-Handler can't be initialized");
  550. }
  551.  
  552.  
  553. /*
  554.  *  ActivateIconify()
  555.  *
  556.  *  Signal the handler that it can proceed, and set the flags so that
  557.  *  DoExit() knows that everything went smoothly (i.e., so that it will
  558.  *  not free the allocated memory, etc).
  559.  */
  560.  
  561. static void ActivateIconify()
  562. {
  563.    Signal(HandlerTask,OKSIGNAL);
  564.    HandlerTask = NULL; Segment = NULL;
  565.    HandlerAdded = FALSE; VectorsSet = FALSE;
  566.    IntuitionBase = NULL;
  567.    GfxBase = NULL;
  568.    LayersBase = NULL;
  569.    AllOK = TRUE;
  570. }
  571.  
  572.  
  573. /*
  574.  *  SetupScreens()
  575.  *
  576.  *  Look through the intuition list of screens and call the handler's
  577.  *  OpenScreen code for each one.  This causes each screen to be processed
  578.  *  by the handler as though it were just openned, hence it will get a
  579.  *  backdrop wIconify window, etc.
  580.  */
  581.  
  582. static void SetupScreens()
  583. {
  584.    struct Screen *theScreen;
  585.    void (*cOpenScreen)() = var(cOpenScreen);
  586.  
  587.    Forbid();
  588.    theScreen = IntuitionBase->FirstScreen;
  589.    while (theScreen)
  590.    {
  591.       (*cOpenScreen)(theScreen);
  592.       theScreen = theScreen->NextScreen;
  593.    }
  594.    Permit();
  595. }
  596.  
  597.  
  598. /*
  599.  *  main()
  600.  *
  601.  *  if wIconify is already running, then
  602.  *    Attempt to end wIconify.
  603.  *    If contact was made, wait for wIconify to confirm that it is done.
  604.  *    If the user cancelled the wait, print a message,
  605.  *    Otherwise, get the initialized variables for clean up
  606.  *  Otherwise, wIconify is not already running, so
  607.  *    Check if the program was called correctly
  608.  *    Load the handler code,
  609.  *    Get the variables needed for setup
  610.  *    Open the libraries
  611.  *    Read the init file, if any
  612.  *    Set the default values for anything not defined in the file
  613.  *    Set the variables to their initialized values
  614.  *    Create the iconify task
  615.  *    Have the handler process all the existing screens
  616.  *    Add the Input Device handler and set the function traps
  617.  *    Report that wIconify is installed.
  618.  *  Exit with clean up
  619.  */
  620.  
  621. void main(argc,argv)
  622. int argc;
  623. char **argv;
  624. {
  625.    ULONG Signals;
  626.    extern struct HandlerData *wEndIconify();
  627.  
  628.    if (wIconifyActive())
  629.    {
  630.       HandlerData = wEndIconify();
  631.       if (HandlerData == NULL) DoExit("Can't get HandlerData from Handler");
  632.       printf("Requesting wIconify to stop...");
  633.       Signals = Wait(OKSIGNAL| CANCELSIGNAL);
  634.       if ((Signals & CANCELSIGNAL) == FALSE)
  635.          GetIconifyVars(), printf("\n");
  636.         else
  637.          printf("[Cancelled]\n");
  638.    } else {
  639.       if (argc > 2) DoExit("Usage:  '%s'",USAGE);
  640.       LoadIconify();
  641.       GetVariables();
  642.       CheckLibOpen(&IntuitionBase,"intuition.library",INTUITION_REV);
  643.       CheckLibOpen(&GfxBase,"graphics.library",GRAPHICS_REV);
  644.       CheckLibOpen(&LayersBase,"layers.library",LAYERS_REV);
  645.       if (argc == 2) ReadInitFile(argv[1],NULL);
  646.          else ReadInitFile(INITFILENAME1,INITFILENAME2);
  647.       SetDefaults();
  648.       SetVariables();
  649.       CreateIconify();
  650.       SetupScreens();
  651.       if (TellInputDevice(IND_ADDHANDLER)) HandlerAdded = TRUE;
  652.         else DoExit("Can't add Input Handler");
  653.       SetVectors();
  654.       ActivateIconify();
  655.       printf("%s v%d.%d.%d installed\n",
  656.          program,var(MajVers),var(MinVers),MAJLOADVERS);
  657.    }
  658.    DoExit(NULL);
  659. }
  660.